package com.bobamrz.frontend;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bobamrz.dao.DocCatalogDAO;
import com.bobamrz.dao.DocStatusTypeDAO;

import com.bobamrz.dao.DocTypeDAO;
import com.bobamrz.dao.DocumentDAO;
import com.bobamrz.domain.DocStatusType;
import com.bobamrz.domain.DocAttribute;
import com.bobamrz.domain.DocCatalog;
import com.bobamrz.domain.DocStatusType;
import com.bobamrz.domain.DocType;
import com.bobamrz.domain.Document;
import com.bobamrz.domain.DocumentDocCatalog;
import com.bobamrz.domain.DocumentDocType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class SaveDocumentJsonServlet extends SuperServlet {

	protected void processGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		/* get all the parameters and parameter values into a map */
				
		Map<String, String> parameters = new TreeMap<String, String>(); 
		Enumeration<String> paramNames = request.getParameterNames();
		while(paramNames.hasMoreElements()) {
			String paramName = (String)paramNames.nextElement();
			String paramValue = "";

			String[] allParamValues = request.getParameterValues(paramName);
			if (allParamValues.length == 1) {
				paramValue = allParamValues[0];
			} else {
				//error message, that one parameter has multiple values
			}
			parameters.put(paramName, paramValue);
		}
			
		
		
		Map<String, Object> validationResult = validateDocument(parameters);

		
		
		/* --- send json-response --- */
		Gson gson = new GsonBuilder().serializeNulls().create();
		String jsonData = gson.toJson(validationResult);
		PrintWriter writer = null;
		try {
			writer = new PrintWriter(response.getOutputStream());
			writer.write(jsonData);
		} finally {
			if (writer != null) {
				writer.close();
			}
		}
		/* -------------------------- */
		
		boolean newDocument = false;
		if("new".equals(parameters.get("id"))) {
			newDocument = true;
		}
		
		if("success".equals(validationResult.get("status"))) {
			if(newDocument) {
				Document document = buildDocumentFromParameters(parameters);
				saveDocumentToDB(document, Long.parseLong(parameters.get("catalog")), parameters.get("docType"));
			} else {
				updateDocumentToDB(parameters);
			}
			
		}
		
	}

	private void updateDocumentToDB(Map<String, String> parameters) {		
		DocumentDAO documentDAO = new DocumentDAO();
		Document doc = documentDAO.getById(Long.parseLong(parameters.get("id")));
		
		doc.setUpdated(new Date());
		doc.setDescription(parameters.get("description"));
		doc.setName(parameters.get("name"));
		
		DocStatusType status = new DocStatusTypeDAO().getDocStatusTypeById(Integer.parseInt(parameters.get("status")));
		doc.setDocStatusType(status);

		documentDAO.save(doc);
	}

	private Map<String, Object> validateDocument(Map<String, String> parameters) {
		DocumentValidator validator = new DocumentValidator();
		Map<String, Object> validationResult = validator.execute(parameters);
		return validationResult;
	}
	
	private Document buildDocumentFromParameters(Map<String, String> parameters) {
		Document document = new Document();
		
		//DocStatusType status = new DocStatusTypeHome().findById(Integer.parseInt(parameters.get("status")));
		DocStatusType status = new DocStatusTypeDAO().getDocStatusTypeById(Integer.parseInt(parameters.get("status")));
		document.setDocStatusType(status);
			
		document.setName(parameters.get("name"));
		document.setDescription(parameters.get("description"));
		
		document.setCreated(new Date());
		document.setCreatedBy(Long.valueOf(1));
		
		document.setUpdated(new Date());
		document.setUpdatedBy(Long.valueOf(1));
		
		return document;
	}
	
	private void saveDocumentToDB(Document document, long catalogId, String docTypeString) {		
		DocumentDAO documentDAO = new DocumentDAO();
		
		DocCatalogDAO docCatalogDAO = new DocCatalogDAO();
		DocCatalog catalog = docCatalogDAO.getById(catalogId);
		catalog.setContentUpdated(new Date());
		Set<DocumentDocCatalog> links = new HashSet<DocumentDocCatalog>();
		DocumentDocCatalog link = new DocumentDocCatalog();
		link.setDocCatalog(catalog);
		link.setDocument(document);
		links.add(link);
		document.setDocumentDocCatalogs(links);

		DocTypeDAO docTypeDAO = new DocTypeDAO();
		DocType docType = docTypeDAO.getDocTypeByDocTypeName(docTypeString);
		Set<DocumentDocType> links2 = new HashSet<DocumentDocType>();
		DocumentDocType link2 = new DocumentDocType();
		link2.setDocType(docType);
		link2.setDocument(document);
		links2.add(link2);
		document.setDocumentDocTypes(links2);
	
		documentDAO.save(document);
		docCatalogDAO.save(catalog);
		docTypeDAO.save(docType);

	}	
}
